package com.swiftair.model
{
	import com.coderanger.OAuthEvent;
	import com.coderanger.OAuthManager;
	import com.coderanger.QueryString;
	import com.swiftair.ApplicationFacade;
	import com.swiftair.model.delegates.JSONDelegate;
	
	import mx.collections.ArrayCollection;
	
	import org.puremvc.as3.interfaces.IProxy;
	import org.puremvc.as3.patterns.proxy.Proxy;
	
    /**
     * A proxy for deal with twitter service
     */
    public class TwitterProxy extends Proxy implements IProxy
    {
		public static const NAME:String = "TwitterProxy";

		// Swiftair OAuth tokens
		private static const CONSUMER_KEY:String    = "PMXdocoQLbMQGf3UxKifQ";
		private static const CONSUMER_SECRET:String = "5zc0ikOa7n6bseGCldDGTgVGObfBWZuVkoq5OktVk";
		private static const OAUTH_DOMAIN:String    = "twitter.com";
		// Twitter URL's
		private static const HOME_TIMELINE_URL:String	= "http://api.twitter.com/1/statuses/home_timeline.json";
		private static const MENTIONS_URL:String 		= "http://api.twitter.com/1/statuses/mentions.json";
		private static const DIRECT_MESSAGES_URL:String = "http://api.twitter.com/1/direct_messages.json";
		// Messages
		private static const AUTHORIZATION_ERROR_MESSAGE:String = "Unable to authorize.";
		private static const ACCESS_ERROR_MESSAGE:String = "A problem occurred and we could not access your account.";
		
		private var _twitauth:OAuthManager;

		public function TwitterProxy (data:Object = null) {
            super (NAME, data);
			_twitauth = new OAuthManager();
			// Setup handlers
			_twitauth.addEventListener(OAuthEvent.ON_REQUEST_TOKEN_RECEIVED, onRequestTokenReceived);				
			_twitauth.addEventListener(OAuthEvent.ON_REQUEST_TOKEN_FAILED, onRequestTokenFailed);
			_twitauth.addEventListener(OAuthEvent.ON_ACCESS_TOKEN_RECEIVED, onAccessTokenReceived);				
			_twitauth.addEventListener(OAuthEvent.ON_ACCESS_TOKEN_FAILED, onAccessTokenFailed);
        }
		
		/**
		 * Redirect to Twitter web page to confirm authorization
		 */
		public function authorize():void {
			_twitauth.consumerKey = CONSUMER_KEY;
			_twitauth.consumerSecret = CONSUMER_SECRET;
			_twitauth.oauthDomain = OAUTH_DOMAIN;
			_twitauth.requestToken();
		}
		
		/**
		 * Grant access to Twitter account
		 */
		public function grant(pin:String):void {
			_twitauth.requestAccessToken(Number(pin));
		}

		public function getHomeTimeline():void {
			var postData:String = _twitauth.getSignedURI("GET", HOME_TIMELINE_URL);
			var postParams:Object = new QueryString(postData).toPostObject();
			
			var delegate:JSONDelegate = new JSONDelegate(this, HOME_TIMELINE_URL, postParams);
			delegate.load(ApplicationFacade.MODEL_STATUSES_LOADED);
		}

		public function getMentions():void {
			var postData:String = _twitauth.getSignedURI("GET", MENTIONS_URL);
			var postParams:Object = new QueryString(postData).toPostObject();
			
			var delegate:JSONDelegate = new JSONDelegate(this, MENTIONS_URL, postParams);
			delegate.load(ApplicationFacade.MODEL_STATUSES_LOADED);
		}
		
		public function getDirectMessages():void {
			var postData:String = _twitauth.getSignedURI("GET", DIRECT_MESSAGES_URL);
			var postParams:Object = new QueryString(postData).toPostObject();
			
			var delegate:JSONDelegate = new JSONDelegate(this, DIRECT_MESSAGES_URL, postParams);
			delegate.load(ApplicationFacade.MODEL_DIRECT_MESSAGES_LOADED);
		}
		
		/* PRIVATE */
		
		private function onRequestTokenReceived(event:OAuthEvent):void {
			try {
				_twitauth.requestAuthorisation();
			} catch(requestError:Error) {
				sendNotification(ApplicationFacade.MODEL_AUTHORIZATION_ERROR, AUTHORIZATION_ERROR_MESSAGE);
			}
		}
		
		private function onRequestTokenFailed(event:OAuthEvent):void {
			sendNotification(ApplicationFacade.MODEL_AUTHORIZATION_ERROR, AUTHORIZATION_ERROR_MESSAGE);
		}
		
		private function onAccessTokenReceived(event:OAuthEvent):void {
			sendNotification(ApplicationFacade.MODEL_ACCESS_GRANTED);
		}
		
		private function onAccessTokenFailed(event:OAuthEvent):void {
			sendNotification(ApplicationFacade.MODEL_ACCESS_ERROR, ACCESS_ERROR_MESSAGE);
		}
	}
}